﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using mojoPortal.Web;
using blackhouse.BlackApart.Web;
using blackhouse.Web.FasterFiles;
using blackhouse.BlackApart.Business.Opinions;
using blackhouse.BlackApart.Business;
using blackhouse.BlackApart.Business.Prices;
using System.Globalization;
using blackhouse.JavaScript.JQuery;
using mojoPortal.Business;
using mojoPortal.Business.WebHelpers;
using blackhouse.Web;
using blackhouse.Aparts.Web.Modules;
using blackhouse.BlackApart.Business.Apartments;
using blackhouse.BlackApart.Business.Reservations;
using blackhouse.Web.Composite;
using blackhouse.mojoPortalExtend.Breadcrumbs;
using blackhouse.BlackApart.Business.Cities;

namespace blackhouse.Aparts.Web.Pages {
    public partial class DisplayApartment : NonCmsBasePage {

        #region Fields

        protected DisplayApartmentTypeState state;
        private StatisticsOpinion statisticsOpinion;
        private IOpinion mostValueableOpinion;
        private double price = 0;
        private SearchState queryState = SearchState.GetFromContext();
        private Factory factory = Factory.Instance();
        private Variant variant;
        private blackhouse.mojoPortalExtend.PageProvider pageProvider;
        private SiteCity city;
        private BreadcrumbsAccess breadcrumbs;
        private PageSettings cmsOpinionPage;

        #endregion

        #region Properties

        public mojoPortalExtend.PageProvider PageProvider {
            get {
                if (this.pageProvider == null)
                    this.pageProvider = new mojoPortalExtend.PageProvider();
                return this.pageProvider;
            }
        }

        public PageSettings CMSOpinionPage {
            get {
                if (this.cmsOpinionPage == null)
                    this.cmsOpinionPage = this.GetCmsOpinionPage();
                return this.cmsOpinionPage;
            }
        }

        #endregion

        #region Event Handlers

        protected override void OnPreInit(EventArgs e) {
            this.AllowSkinOverride = true;
            if (string.IsNullOrEmpty(Request["skin"]))
                HttpContext.Current.Items.Add("skin", "blackhouse");
            base.OnPreInit(e);
        }

        protected override void OnInit(EventArgs e) {
            base.OnInit(e);

            DisplayApartmentTypeState.RedirectIfIncorectUrl();
            this.state = DisplayApartmentTypeState.GetCurrentState();
            this.statisticsOpinion = Factory.Instance().GetStatisticsOpinion();
            this.statisticsOpinion.SetFilterByApartmentType(this.state.ApartmentType.Id);
            this.mostValueableOpinion = this.statisticsOpinion.GetMostValuableOpinion(this.state.ApartmentType.Id, TimeSpan.FromDays(90), CultureInfo.CurrentCulture.Name);
            this.city = factory.GetSiteCity();
            this.breadcrumbs = new BreadcrumbsAccess();
            if (this.queryState.IsSet) {
                FreeApartments search = new FreeApartments(this.queryState.ArrivalDate, this.queryState.DepartureDate, this.queryState.PeopleCount);
                search.FilterToApartmentType(this.state.ApartmentType.Id);
                
                if (search.Count() > 0)
                    variant = search.OrderBy(v => v.Price.GetPrice()).FirstOrDefault();
            }
            if (variant != null)
                this.price = variant.Price.GetPricePerNight();
            else
                this.price = this.CalculatePriceFrom();
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);

            this.PopulateControls();
            this.AddJs();
            this.SetSeo();
            this.SetBreadcrumbs();
        }

        #endregion

        #region Methods

        private PageSettings GetCmsOpinionPage() {
            return this.PageProvider.FindCmsPageByFunctionality("opinions");
        }

        private void SetBreadcrumbs() {
            PageSettings ps = this.PageProvider.FindCmsPage("~/apartments");
            if (ps != null)
                this.breadcrumbs.AddCrumb(string.Format(ps.PageName, this.city.SentenceName.ToFirstUpperString()),
                    UrlUtils.LocalizeUrl("/" + HttpContext.GetGlobalResourceObject("Aparts", "apartmentsUrl") + '-' + this.city.UrlName));
            this.breadcrumbs.AddCrumb(this.state.ApartmentType.ShortName, UrlUtils.GetApartmentTypeUrl(Factory.Instance().GetPreFolderEvaluation(), this.state.ApartmentType, this.state.View, this.state.Page));
        }

        private void SetSeo() {
            this.PageProvider.SetCanonicalUrl(UrlUtils.GetApartmentTypeUrl(Factory.Instance().GetPreFolderEvaluation(), this.state.ApartmentType, this.state.View, this.state.Page));
            this.PageProvider.SetPageTitle(this.state.ApartmentType.GetSeo().PageTitle);
            this.PageProvider.SetPageKeywords(this.state.ApartmentType.GetSeo().PageKeywords);
            this.PageProvider.SetPageDescription(this.state.ApartmentType.GetSeo().PageDescription);
        }

        private double CalculatePriceFrom() {
            IApartmentPrice price = Factory.Instance().GetApartmentGroupPrice(this.state.ApartmentType);
            return price.GetPromoPriceFrom(this.state.ApartmentType);
        }

        private string GetOpinionUrl(PageSettings opinionPage) {
            string url = opinionPage.Url;
            url = url.ReplaceEx("~/", "/");
            if (url.EndsWith("/"))
                url = url.Substring(0, url.Length - 1);
            return UrlUtils.LocalizeUrl(url);
        }

        private void PopulateControls() {
            (this.Master.FindControl("divCenter") as Panel).Visible = false;

            this.lblApartmentName.Text = this.state.ApartmentType.Name;
            this.lblApartmentName2.Text = this.state.ApartmentType.Name;
            if (this.lblOpinionTextState != null)
                this.lblOpinionTextState.Text = this.statisticsOpinion.GetAverageRatingText();
            this.lnkOpinionNumbers.Text = this.statisticsOpinion.BasedOnNumberOfOpinions() + " " + GetGlobalResourceObject("Aparts", "scoreOpinion");


            PageSettings opinionPage = this.CMSOpinionPage;
            string opinionUrl = string.Empty;
            if (opinionPage != null) 
                opinionUrl = GetOpinionUrl(opinionPage);

            string opinionNavigateUrl = opinionUrl;
            if (this.lnkOpinionNumbers != null)
                this.lnkOpinionNumbers.NavigateUrl = opinionNavigateUrl;
            if (this.lnkToOpinions != null)
                this.lnkToOpinions.NavigateUrl = opinionNavigateUrl;

            List<string> locBuild = new List<string>(3);
            IApartmentLocation location = this.state.ApartmentType.DefaultLocalization;
            if (!string.IsNullOrEmpty(location.City))
                locBuild.Add(location.City);
            if (!string.IsNullOrEmpty(location.District))
                locBuild.Add(location.District);
            if (!string.IsNullOrEmpty(location.LocationName))
                locBuild.Add(location.LocationName);

            this.ltlAddress.Text = string.Join(", ", locBuild.ToArray());

            string virtualViewLink = "/VirtualView/" + this.state.ApartmentType.Id + "/1.swf";
            if (this.lnkToVirtualView != null)
                this.lnkToVirtualView.NavigateUrl = virtualViewLink;

            if (this.bhImportantPlaces != null)
                this.bhImportantPlaces.ReferenceLocation = this.state.ApartmentType.DefaultLocalization.Localization;

            //this.lnkToPopupReservation.Apartment = this.state.ApartmentType;
            
            this.ltlSurface.Text = this.state.ApartmentType.AreaSize.ToString();

            this.pnlPeople.Width = Unit.Pixel(this.state.ApartmentType.NumberOfPeople * 11);
            if (!string.IsNullOrEmpty(this.lnkPeople.ToolTip) && this.lnkPeople.ToolTip.Contains("{0}"))
                this.lnkPeople.ToolTip = string.Format(this.lnkPeople.ToolTip, this.state.ApartmentType.NumberOfPeople);

            this.lblPrice.Value = this.price;

            if (this.queryState.IsSet && this.variant != null)
                PopulateSetQuery();
            else
                PopulateNotSetQuery();

            this.PopulateMostValueableOpinion();

            this.OnlineReservation1.DisplayForApartmentId = this.state.ApartmentType.Id;
        }

        private void PopulateNotSetQuery() {
            CompositeControl<Control> visibles = new CompositeControl<Control>(this.ltlPriceProm, this.ltlPricePer);
            visibles.SetVisible(true);
        }

        private void PopulateSetQuery() {
            CompositeHyperLink links = new CompositeHyperLink(this.lnkToMakeReservation);
            CompositeControl<Control> visibles = new CompositeControl<Control>(this.ltlPrice, this.ltlPricePerNight);

            links.SetVisible(true);
            links.SetNavigateUrl(UrlUtils.LocalizeUrl(string.Format("/pages/progressreservation.aspx?search={0}&group={1}", this.queryState, this.state.ApartmentType.Id)));
            links.SetToolTip(this.state.ApartmentType.Name);
            this.lblPrice.Precision = 2;

            visibles.SetVisible(true);

            //this.lnkDynReservation2.Apartment = this.state.ApartmentType;
            this.PopulateLnkDynReservation2Text();
        }

        private void PopulateMostValueableOpinion() {
            if (this.mostValueableOpinion != null) {
                this.lblMostOpinionStateCut.Text = this.mostValueableOpinion.InPlusOpinion;
                this.lblMostOpinionStateCut.ToolTip = this.mostValueableOpinion.InPlusOpinion;
                //if (this.lblMostOpinionState.Text.Length > 70)
                //    this.lblMostOpinionState.Text = this.lblMostOpinionState.Text.Substring(0, 70);
                this.lblMostOpinionCategory.Text = this.mostValueableOpinion.Publisher.Category;
                this.lblMostOpinionDate.Text = this.mostValueableOpinion.PublishedDate.ToString("D");
            }
        }

        private void PopulateLnkDynReservation2Text() {
            string param1, param2, param3, param4, param5;

            int param1_val = Convert.ToInt32((this.queryState.DepartureDate.Date - this.queryState.ArrivalDate.Date).TotalDays);

            param1 = param1_val + " ";
            if (param1_val == 1)
                param1 += "dzień";
            else
                param1 += "dni";
            param2 = this.queryState.ArrivalDate.ToString(this.GetFormatArrivalDate());
            param3 = this.queryState.DepartureDate.ToString("d MMMM yyyy");

            param4 = this.queryState.PeopleCount + " ";
            if (this.queryState.PeopleCount == 1)
                param4 += "osoby";
            else
                param4 += "osób";

            param5 = "";
            if (this.variant.ApartmentCount > 1)
                param5 = "(" + this.variant.ApartmentCount + " apartamenty)";

            //this.lnkDynReservation2.Text = string.Format(this.lnkDynReservation2.Text, param1, param2, param3, param4, param5);
        }

        private string GetFormatArrivalDate() {
            if (queryState.ArrivalDate.Year != queryState.DepartureDate.Year)
                return "d MMMM yyyy";
            else {
                string format = "d ";
                if (queryState.ArrivalDate.Month != queryState.DepartureDate.Month)
                    format += "MMMM";
                return format;
            }

        }

        private void AddJs() {
            JQueryLibraries jql = new JQueryLibraries();
            jql.IncludeJQueryFancybox();
            jql.IncludeFileBasedOnJQuery("blackhouse.Aparts.Web.Scripts.displayApartment.js,blackhouse.Aparts.Web");
            FasterFilesProvider files = new FasterFilesProvider();
            files.AddBeforeScript(string.Format(@"var apartSmGalleryParameterThumbSize = '{0}x{1}';
var apartSmGalleryParameterPhotoSize = '440x330';
var apartSmGalleryParameterFullPhotoSize = '{2}x{3}'", ImageSizeUtils.ApartmentPhotoSmall.Width, ImageSizeUtils.ApartmentPhotoSmall.Height, ImageSizeUtils.ApartmentPhotoFull.Width, ImageSizeUtils.ApartmentPhotoFull.Height));
            files.AddAfterScript("$(function(){$('.navigateToOpinions').wrap('<a href=\"" + UrlUtils.GetOpinionsUrl(Factory.Instance().GetPreFolderEvaluation(), this.state.ApartmentType, null, 1) + "\"></a>')});");
        }

        #endregion

    }
}